#include "thread.h"
#include<sys/sendfile.h>
#include<func.h>
int userupdate(char* filename,int fileNameLen,int netfd,dirID_t * dir){
    train_t newFile;
    int ret=0;
    newFile.length=fileNameLen;
    long long maxsize=1LL*1024*1024*1024*2;
    int changesize=1024*1024*100;
    char path[4096];
    bzero(path,4096);
    char userdir[4096];                                                               
    bzero(userdir,4096);
    get_user_dir(userdir,dir);
    sprintf(path,"%s/%s",userdir,filename);
    memcpy(newFile.buf,filename,fileNameLen);
    ret=send(netfd,&newFile,sizeof(newFile.length)+newFile.length,MSG_NOSIGNAL);
    ERROR_CHECK(ret,-1,"send");
    int fd=open(path,O_RDWR);
    struct stat statbuf;
    fstat(fd,&statbuf);
    newFile.length=statbuf.st_size;

    if(newFile.length>maxsize){
        perror("too huge docunment");
        return -1;
    }        
    memcpy(newFile.buf,&statbuf.st_size,newFile.length);
    ret=send(netfd,&newFile,sizeof(newFile.length)+newFile.length,MSG_NOSIGNAL);
    ERROR_CHECK(ret,-1,"send");
    if(newFile.length>changesize){
        ftruncate(fd,statbuf.st_size);
    char *p = (char *)mmap(NULL,statbuf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    off_t totalsize = 0;
    while(totalsize < statbuf.st_size){
        if(statbuf.st_size - totalsize > (long )sizeof(newFile.buf)){
            newFile.length = sizeof(newFile.buf);
        }
        else{
            newFile.length = statbuf.st_size - totalsize;
        }
        send(netfd,&newFile.length,sizeof(newFile.length),MSG_NOSIGNAL);
        send(netfd,p+totalsize,newFile.length,MSG_NOSIGNAL);
        totalsize += newFile.length;
    }
    newFile.length = 0;
    send(netfd,&newFile.length,sizeof(newFile.length),MSG_NOSIGNAL);
    munmap(p,statbuf.st_size);
    }else{
    sendfile(netfd,fd,NULL,statbuf.st_size);
    }
    return 0;
}

